import React from 'react';
import { message, Tag } from 'antd';
import { customUpload } from '@/utils/fileUpload';
import BraftEditor from 'braft-editor';
import { ContentUtils } from 'braft-utils';
import 'braft-extensions/dist/table.css';
import Table from 'braft-extensions/dist/table';
import { debounce } from 'lodash';
// import { useRequest } from '@/hooks';
import styles from './index.less';

const MyComponent = ({ dataSource = [], onClick, ...restProps }) => {
    const liStyle = {
        backgroundColor: 'hsla(0,0%,100%,.1)',
        borderRadius: 2,
        margin: 5,
        color: '#fff',
        fontSize: 12,
        height: 30,
        lineHeight: '30px',
        textAlign: 'center',
        cursor: 'pointer'
    };

    return (
        <ul style={{ width: 110, maxHeight: 250, overflow: 'auto' }} {...restProps}>
            {dataSource?.map(item => (
                <li
                    style={liStyle}
                    key={item.field}
                    onClick={() => {
                        if (onClick) {
                            onClick(item);
                        }
                    }}
                >
                    {item.value}
                </li>
            ))}
        </ul>
    );
};

let editorId = 1;

const channelColumns = [
    {
        field: 'employeeName',
        value: '新员工姓名'
    },
    {
        field: 'companyName',
        value: '新员工行政机构'
    },
    {
        field: 'organizationName',
        value: '新员工组织机构'
    },
    {
        field: 'dutyName',
        value: '新员工岗位'
    },
    {
        field: 'entryDate',
        value: '新员工入职日期'
    },
    {
        field: 'expectRegularDate',
        value: '新员工转正日期'
    }
];

const BraftTemplate = ({
    initialValue,
    onChange,
    readOnly,
    hasField = true,
    prefix,
    placeholder = '请输入邮件内容',
    ...restProps
}) => {
    const idRef = React.useRef(0);
    const editorRef = React.useRef(
        BraftEditor.createEditorState(null, {
            editorId: `${prefix}editor-with-entity-${editorId}`
        })
    );
    const [editorValue, setEditorValue] = React.useState(editorRef.current);
    const [flag, setFlag] = React.useState(false);

    const options = {
        defaultColumns: 4, // 默认列数
        defaultRows: 7, // 默认行数
        withDropdown: false, // 插入表格前是否弹出下拉菜单
        columnResizable: true, // 是否允许拖动调整列宽，默认false
        exportAttrString: 'border="1" style="border-collapse: collapse"', // 指定输出HTML时附加到table标签上的属性字符串
        includeEditors: [`${prefix}editor-with-entity-${editorId}`]
    };

    const entityExtension = {
        // 指定扩展类型
        type: 'entity',
        // 指定该扩展对哪些编辑器生效，不指定includeEditors则对所有编辑器生效
        includeEditors: [`${prefix}editor-with-entity-${editorId}`],
        // 指定扩展的entity名称，推荐使用全部大写，内部也会将小写转换为大写
        name: 'COLUMN-ITEM',
        // 指定entity的mutability属性，可选值为MUTABLE和IMMUTABLE，表明该entity是否可编辑，默认为MUTABLE
        mutability: 'IMMUTABLE',
        // 指定entity在编辑器中的渲染组件
        component: props => {
            const entity = props.contentState.getEntity(props.entityKey);
            const { foo, id } = entity.getData();
            const handleRemove = () => {
                const childrenText = props.children?.[0]?.props?.text || '';
                const html = editorRef.current
                    .toHTML()
                    .replace(`<span data-foo="${foo}" data-id="${id}" class="column-item">${childrenText}</span>`, '');
                const obj = BraftEditor.createEditorState(html, {
                    editorId: `${prefix}editor-with-entity-${editorId}`
                });
                setEditorValue(obj);
            };
            return (
                <Tag
                    key={id}
                    closable={!readOnly}
                    style={{
                        paddingTop: 4,
                        paddingBottom: 4,
                        marginLeft: 4,
                        marginRight: 4,
                        marginBottom: 4,
                        textIndent: 0,
                        background: '#F0F7FF',
                        border: '1px solid #F0F7FF'
                    }}
                    onClose={() => handleRemove()}
                >
                    {props.children}
                </Tag>
            );
        },
        // 指定html转换为editorState时，何种规则的内容将会转换成该entity
        // eslint-disable-next-line consistent-return
        importer: (nodeName, node) => {
            // source属性表明输入来源，可能值为create、paste或undefined
            if (nodeName.toLowerCase() === 'span' && node.classList && node.classList.contains('column-item')) {
                // 此处可以返回true或者一个包含mutability和data属性的对象
                let tempId = 0;
                if (node.dataset.id) {
                    tempId = node.dataset.id;
                } else {
                    idRef.current += 1;
                    tempId = idRef.current;
                }
                return {
                    mutability: 'IMMUTABLE',
                    data: {
                        id: tempId,
                        foo: node.dataset.foo
                    }
                };
            }
        },
        // 指定输出该entnty在输出的html中的呈现方式
        exporter: (entityObject, originalText) => {
            // 注意此处的entityObject并不是一个entity实例，而是一个包含type、mutability和data属性的对象
            const { foo, id } = entityObject.data;
            return (
                <span data-foo={foo} data-id={id} className="column-item">
                    {originalText}
                </span>
            );
        }
    };

    // 加载扩展模块
    React.useEffect(() => {
        BraftEditor.use(Table(options));
        BraftEditor.use(entityExtension);
    }, [editorId]);

    const formatInitialValue = str => {
        if (!str) {
            return '';
        }
        let tempStr = str;
        const arr = str.match(/\${[a-zA-Z]+}/g);
        if (arr && arr.length > 0) {
            arr.forEach(item => {
                const field = item.replace('${', '').replace('}', '');
                const fieldName = channelColumns.find(c => c.field === field)?.value || '';
                tempStr = tempStr.replace(item, `<span data-foo="${field}" class="column-item">${fieldName}</span>`);
            });
        }
        return tempStr;
    };

    const handleInsert = column => {
        const content = `\${${column?.field}}`;
        const obj = ContentUtils.insertText(editorRef.current, content);
        setFlag(true);
        setEditorValue(obj);
    };

    // 不允许添加尺寸大于10M的文件
    const myValidateFn = file => {
        if (file.size > 1024 * 1024 * 10) {
            message.error('图片不能大于10M！');
            return false;
        }
        return true;
    };

    // 报错提示
    const handleEditorChange = editorState => {
        setEditorValue(editorState);
    };

    const myUploadFn = param => {
        const onSuccess = (response, file) =>
            param.success({
                url: response.data[0].url,
                meta: {
                    id: file.name,
                    title: file.name,
                    alt: file.name
                }
            });
        customUpload({ files: param, onSuccess });
    };

    const debounceFn = React.useRef(
        debounce(html => {
            if (onChange) onChange(html);
        }, 300)
    );

    React.useEffect(() => {
        const html = editorValue.toHTML();
        if (flag) {
            setFlag(false);
            setEditorValue(
                BraftEditor.createEditorState(formatInitialValue(html), {
                    editorId: `${prefix}editor-with-entity-${editorId}`
                })
            );
        }
        editorRef.current = editorValue;
        debounceFn.current(html);
    }, [editorValue]);

    React.useEffect(() => {
        setEditorValue(
            BraftEditor.createEditorState(formatInitialValue(initialValue), {
                editorId: `${prefix}editor-with-entity-${editorId}`
            })
        );
    }, [initialValue]);

    React.useEffect(
        () => () => {
            idRef.current = 0;
            editorId += 1;
        },
        []
    );

    const defaultControls = [
        'undo',
        'redo',
        'separator',
        'font-size',
        'line-height',
        'letter-spacing',
        'separator',
        'text-color',
        'bold',
        'italic',
        'underline',
        'strike-through',
        'separator',
        'superscript',
        'subscript',
        'remove-styles',
        'emoji',
        'separator',
        'text-indent',
        'text-align',
        'separator',
        'headings',
        'list-ul',
        'list-ol',
        'blockquote',
        'code',
        'separator',
        'media',
        'link',
        'table',
        'hr',
        'separator',
        'clear'
    ];

    const fieldMap = {
        key: 'my-dropdown',
        type: 'dropdown',
        title: '插入参数',
        className: 'my-dropdown',
        html: null,
        text: '插入参数',
        showArrow: true,
        arrowActive: false,
        autoHide: true,
        component: <MyComponent dataSource={channelColumns} onClick={handleInsert} />
    };

    const controls = hasField ? [...defaultControls, fieldMap] : defaultControls;

    const defaultEditorProps = {
        controls,
        media: {
            uploadFn: myUploadFn,
            validateFn: myValidateFn,
            accepts: {
                image: 'image/png,image/jpeg,image/gif'
            }
        },
        excludeControls: ['fullscreen'],
        imageControls: [
            {
                onClick: block => {
                    console.log(block);
                }
            },
            'align-left',
            'align-center',
            'align-right',
            'size',
            'remove'
        ],
        contentStyle: { height: 600 }
    };

    const readOnlyEditorProps = {
        controls: [],
        readOnly,
        // style: {
        //     border: 'none'
        // },
        contentStyle: { height: 'auto' }
    };

    return (
        <BraftEditor
            id={`${prefix}editor-with-entity-${editorId}`}
            className={styles.customEditor}
            value={editorValue}
            onChange={handleEditorChange}
            placeholder={readOnly ? '' : placeholder}
            contentStyle={{ height: 600 }}
            {...(readOnly ? readOnlyEditorProps : defaultEditorProps)}
            {...restProps}
        />
    );
};

export default BraftTemplate;
